<template>
  <a-layout-content style="padding:0 10px;width: 100%; height: 100%;">
    <a-form
      id="form"
      ref="formModelRef"
      :model="formModel"
      :size="formConfig.size"
      :layout="formConfig.layout"
      :label-align="formConfig.labelAlign"
      :label-col-props="formConfig.labelColProps"
      :wrapper-col-props="formConfig.wrapperColProps"
    >
      <draggable
        v-model:list="formList"
        item-key="id"
        class="draggable-container"
        handle=".btn-drag"
        :force-fallback="true"
        :fallback-class="true"
        :fallback-on-body="true"
        :group="{ name: 'select', pull : false, put: true }"
        @add="onDragAdd"
      >
        <template #item="{ element }">
          <template v-if="element.group === 'container'">
            <component
              :is="element.component"
              :id="element.id"
              v-model="formModel"
              :item="element"
              :item-config="element.itemConfig"
              :config="element.config"
              @select-item="selectItem"
              @delete-item="deleteItem"
              @copy-item="copyItem"
            />
          </template>
          <template v-else>
            <component
              :is="element.component"
              :id="element.id"
              v-model="formModel[element.id]"
              :item="element"
              :item-config="element.itemConfig"
              :config="element.config"
              @select-item="selectItem"
              @delete-item="deleteItem"
              @copy-item="copyItem"
            />
          </template>
        </template>
      </draggable>
    </a-form>
  </a-layout-content>
</template>

<script lang="ts" setup>
import { inject, defineModel, defineEmits } from 'vue';
import { cloneDeep } from 'lodash';
import { getFormItemId } from '@/components/form-design/utils';
import { FormItemConfig } from '@/components/form-design/item-select/config/type';
import Draggable from 'vuedraggable';

const formConfig = inject('formConfig');

const formList = defineModel<Array<FormItemConfig>>('list', { type: Array, default: [] });

const formModel = defineModel('model', { type: Object, default: {} });

const emits = defineEmits(['selectItem', 'deleteItem', 'copyItem']);

const onDragAdd = (event: any) => {
  console.log('onDragAdd', event);
};

const selectItem = (value: any) => {
  emits('selectItem', value);
};
// 删除组件
const deleteItem = (value: any) => {
  console.log('deleteItem', value);
  let hasItem = false;
  const childrenItemList = [];
  for (let i = 0; i < formList.value.length; i += 1) {
    const item = formList.value[i];
    if (item.id === value.id) {
      hasItem = true;
      formList.value = formList.value.filter(item => item.id !== value.id);
      emits('deleteItem', value);
      return;
    }
    if (item.formList && item.formList.length > 0) {
      childrenItemList.push(item);
    }
  }
  if (hasItem) {
    return;
  }
  if (childrenItemList.length > 0) {
    childrenItemList.forEach(item => {
      deleteItemChildren(value, item);
    });
  }
};

// 递归删除子组件
const deleteItemChildren = (value: any, childrenItem: any) => {
  let hasItem = false;
  const childrenItemList: any[] = [];
  for (let i = 0; i < childrenItem.formList.length; i += 1) {
    const item = childrenItem.formList[i];
    if (item.id === value.id) {
      hasItem = true;
      // @ts-ignore
      childrenItem.formList = childrenItem.formList.filter(item => item.id !== value.id);
      emits('deleteItem', value);
      return;
    }
    if (item.formList && item.formList.length > 0) {
      childrenItemList.push(item);
    }
  }
  if (hasItem) {
    return;
  }
  if (childrenItemList.length > 0) {
    childrenItemList.forEach(item => {
      deleteItemChildren(value, item);
    });
  }
};

// 复制组件
const copyItem = (value: any) => {
  let hasItem = false;
  const childrenItemList = [];
  for (let i = 0; i < formList.value.length; i += 1) {
    const item = formList.value[i];
    if (item.id === value.id) {
      hasItem = true;
      const copyValue = cloneDeep(value);
      copyValue.id = getFormItemId(value.type);
      setItemId(copyValue);
      formList.value.push(copyValue);
      emits('copyItem', value);
      return;
    }
    if (item.formList && item.formList.length > 0) {
      childrenItemList.push(item);
    }
  }
  if (hasItem) {
    return;
  }
  if (childrenItemList.length > 0) {
    childrenItemList.forEach(item => {
      copyItemChildren(value, item);
    });
  }
};

// 递归查找要复制的组件
const copyItemChildren = (value: FormItemConfig, childrenItem: any) => {
  let hasItem = false;
  const childrenItemList: any[] = [];
  for (let i = 0; i < childrenItem.formList.length; i += 1) {
    const item = childrenItem.formList[i];
    if (item.id === value.id) {
      hasItem = true;
      const copyValue = cloneDeep(value);
      copyValue.id = getFormItemId(value.type);
      setItemId(copyValue);
      childrenItem.formList.push(copyValue);
      emits('copyItem', value);
      return;
    }
    if (item.formList && item.formList.length > 0) {
      childrenItemList.push(item);
    }
  }
  if (hasItem) {
    return;
  }
  if (childrenItemList.length > 0) {
    childrenItemList.forEach(item => {
      copyItemChildren(value, item);
    });
  }
};

const setItemId = (item: FormItemConfig) => {
  if (item.formList && item.formList.length > 0) {
    item.formList.forEach(children => {
      children.id = getFormItemId(children.type);
      setItemId(children);
    });
  }
};
</script>

<script lang="ts">
export default {
  name: 'FormContainer'
};
</script>

<style lang="less" scoped>
.draggable-container {
  width: 100%;
  min-height: 600px;
}

.item-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  flex-wrap: wrap;
}

.item {
  margin-bottom: 5px;
  padding: 5px 5px;
  width: 49%;
  background-color: var(--color-bg-1);
  border: var(border-1) solid var(color-border-4);
}
</style>